﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Web.UI.WebControls;
using Q.Framework.Extension;
using System.Web.UI;
using System.Web;
using System.Data;
using System.Data.OleDb;

namespace Q.Framework.Utility
{
    public enum ExportationType
    {
        PDF, CSV, XLS
    }

    public static class GridExportation
    {
        static public void Export(ExportationType type, GridView gridView, String fileName = "")
        {
            fileName = fileName.IsNullOrWhiteSpace() ? (gridView.Page != null ? gridView.Page.GetType().Name + "_" : "") + DateTime.Now.Format(FormatDateTime.InvertedDateTime) : fileName;
            switch (type)
            {
                case ExportationType.PDF: ExportGridViewToPDF(gridView, fileName);
                    break;
                case ExportationType.CSV: ExportGridViewToCSV(gridView, fileName);
                    break;
                case ExportationType.XLS: ExportGridViewToXLS(gridView, fileName);
                    break;
                default:
                    break;
            }
        }

        static public void ExportGridViewToXLS(GridView gridView)
        {
            ExportGridViewToXLS(gridView, (gridView.Page != null ? gridView.Page.GetType().Name + "_" : "") + DateTime.Now.Format(FormatDateTime.InvertedDateTime));
        }

        static public void ExportGridViewToXLS(GridView gridView, String nomeArquivo)
        {
            ExportGridViewToXLS(gridView, null, nomeArquivo);
        }

        static public void ExportGridViewToXLS(GridView gridView, GridView gridView2, String nomeArquivo)
        {
            String fileName = nomeArquivo + ".XLS";
            StringWriter stringWriter = new StringWriter();
            HtmlTextWriter htmlWriter = new HtmlTextWriter(stringWriter);

            if ((gridView.Rows.Count != 0) || (gridView2 != null && gridView2.Rows.Count != 0))
            {
                if (gridView.Rows.Count != 0)
                    InternalGetGridContent(gridView, htmlWriter);

                if (gridView2 != null && gridView2.Rows.Count != 0)
                    InternalGetGridContent(gridView2, htmlWriter);
            }
            else
                if (gridView.Columns.Count == 0 && (gridView2 == null || (gridView2 != null && gridView2.Columns.Count == 0)))
                    throw new ValidationException("Não existe dados para transferir para a planilha");

            HttpContext.Current.Response.Clear();
            HttpContext.Current.Response.Buffer = true;
            HttpContext.Current.Response.ContentType = "application/vnd.ms-excel";
            HttpContext.Current.Response.Charset = "";
            HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.GetEncoding("iso-8859-1");
            HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment; filename=" + fileName);
            HttpContext.Current.Response.Write(stringWriter.ToString());
            HttpContext.Current.Response.End();
        }

        static public void ExportGridViewToPDF(GridView gridView)
        {
            ExportGridViewToPDF(gridView, (gridView.Page != null ? gridView.Page.GetType().Name + "_" : "") + DateTime.Now.Format(FormatDateTime.InvertedDateTime));
        }

        static public void ExportGridViewToPDF(GridView gridView, String nomeArquivo)
        {
            if (gridView.Rows.Count == 0)
                throw new ValidationException("Não existe dados para tranferir para PDF");

            HttpContext.Current.Response.Clear();
            HttpContext.Current.Response.Buffer = true;
            HttpContext.Current.Response.ContentType = "application/pdf";
            HttpContext.Current.Response.Charset = "";
            StringWriter sw = new StringWriter();
            HtmlTextWriter htw = new HtmlTextWriter(sw);
            gridView.RenderControl(htw);

            String fileName = nomeArquivo + ".pdf";
            HttpContext.Current.Response.AddHeader("content-disposition", "attachment; filename=" + fileName);
            HttpContext.Current.Response.Write(sw.ToString());
            HttpContext.Current.Response.End();
        }

        static public void ExportGridViewToCSV(GridView gridView)
        {
            ExportGridViewToCSV(gridView, (gridView.Page != null ? gridView.Page.GetType().Name + "_" : "") + DateTime.Now.Format(FormatDateTime.InvertedDateTime));
        }

        static public void ExportGridViewToCSV(GridView gridView, String nomeArquivo)
        {
            String separator = ";";

            var columns = gridView.Columns.Cast<DataControlField>().Select(c => HttpUtility.HtmlDecode(c.HeaderText).Replace(separator, String.Empty));
            var rows = gridView.Rows.Cast<GridViewRow>().Select(r => String.Join(separator, r.Cells.Cast<TableCell>().Select(c => HttpUtility.HtmlDecode(c.Text))));
            var table = String.Join(separator, columns) + Environment.NewLine + String.Join(Environment.NewLine, rows);

            String fileName = nomeArquivo + ".CSV";
            HttpContext.Current.Response.Clear();
            HttpContext.Current.Response.Buffer = true;
            HttpContext.Current.Response.ContentType = "text/CSV";
            HttpContext.Current.Response.Charset = "";
            HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.GetEncoding("iso-8859-1");
            HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment; filename=" + fileName);
            HttpContext.Current.Response.Write(table);
            HttpContext.Current.Response.End();
        }

        static public GridView GetNewBoundGridView(object dataSource, DataControlFieldCollection dataControlFieldCollection)
        {
            GridView gridView = new GridView() { DataSource = dataSource, AutoGenerateColumns = false };
            foreach (DataControlField dcf in dataControlFieldCollection) gridView.Columns.Add(dcf);
            gridView.DataBind();

            return gridView;
        }

        static private void InternalGetGridContent(GridView gridView, HtmlTextWriter htmlWriter)
        {
            if (!String.IsNullOrEmpty(htmlWriter.InnerWriter.ToString()))
                htmlWriter.WriteLine(" ");

            if (gridView != null)
                if (gridView.Rows.Count != 0)
                    gridView.RenderControl(htmlWriter);
                else
                {
                    GridView blankGridView = new GridView();
                    foreach (String header in gridView.Columns.Cast<DataControlField>().Select(d => d.HeaderText))
                        blankGridView.Columns.Add(new BoundField() { HeaderText = header });

                    blankGridView.AutoGenerateColumns = false;
                    blankGridView.DataSource = new Object[1];
                    blankGridView.DataBind();
                    blankGridView.RenderControl(htmlWriter);
                }
        }

        static public DataTable ImportFromExcelFile(String fileName, String tabName)
        {
            string connectionString = String.Format(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=""Excel 8.0;HDR=NO;""", fileName);

            using (var connection = new OleDbConnection(connectionString))
            using (var dataAdapter = new OleDbDataAdapter(String.Format("select * from [{0}$]", tabName), connection))
            {
                connection.Open();

                DataSet dataset = new DataSet();
                dataAdapter.Fill(dataset);
                return dataset.Tables[0];
            }
        }
    }
}
